package net.ikenway.springboot.demo.Controller;

import com.google.gson.Gson;
import net.ikenway.springboot.demo.Model.Dto.OrderDto;
import net.ikenway.springboot.demo.Model.Dto.ResponseBodyDto;
import net.ikenway.springboot.demo.Model.Entity.Order;
import net.ikenway.springboot.demo.Model.Entity.User;
import net.ikenway.springboot.demo.Service.Implement.AddressServiceImpl;
import net.ikenway.springboot.demo.Service.Implement.OrderServiceImpl;
import net.ikenway.springboot.demo.Utils.SpringContextUtil;
import net.ikenway.springboot.demo.Utils.ValidateErrorMsgUtil;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.ResourceUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.persistence.EntityNotFoundException;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.nio.file.Paths;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author MasterKenway <zk@ikenway.net>
 * @Description
 * @date Created Date 12/18/2020
 */
@RestController
@RequestMapping(value = "/api/order")
public class OrderController {
    private final OrderServiceImpl orderService;
    private final AddressServiceImpl addressService;

    @Autowired
    OrderController(OrderServiceImpl orderService, AddressServiceImpl addressService) {
        this.orderService = orderService;
        this.addressService = addressService;
    }

    @RequestMapping(value = "/findAll", method = RequestMethod.GET)
    public ResponseBodyDto findAll(@RequestParam(required = false) String status) {
        List<OrderDto> orderDtos;
        try {
            if (SpringContextUtil.getCurrentUser().getIdentity() != User.Identity.CUSTOMER) {
                if (status == null) orderDtos = orderService.findAll();
                else orderDtos = orderService.findByStatus(status);
            } else {
                throw new Exception("无权限访问");
            }

        } catch (Exception exception) {
            return new ResponseBodyDto(500, exception.getMessage());
        }
        return new ResponseBodyDto(200, "查询成功", orderDtos);
    }

    @RequestMapping(value = "/findAllByCurrentUser", method = RequestMethod.GET)
    public ResponseBodyDto findAllByCurrentUser() {
        List<OrderDto> orderDtos;
        try {
            orderDtos = orderService.findAllByCurrentUser();
        } catch (Exception exception) {
            return new ResponseBodyDto(500, exception.getMessage());
        }
        return new ResponseBodyDto(200, "查询成功", orderDtos);
    }

    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public ResponseBodyDto create(@Valid @RequestBody OrderDto orderDto, BindingResult bindingResult) {
        Map<String, Object> data = new HashMap<>();

        try {
            if (bindingResult.hasErrors())
                throw new Exception(ValidateErrorMsgUtil.getFirstFormatMsg(bindingResult.getAllErrors()));

            if (orderDto.getAddressId() == null && orderDto.getType() == Order.Type.TAKEOUT)
                throw new Exception("配送地址不能为空");
            orderDto.setCreateTime(new Timestamp(System.currentTimeMillis()));
            Order order = orderService.create(orderDto);
            data.put("orderId", order.getOrderId());
        } catch (Exception entityNotFoundException) {
            return new ResponseBodyDto(500, entityNotFoundException.getMessage());
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return new ResponseBodyDto(200, "下单成功", data);
    }

    @RequestMapping(value = "/pay", method = RequestMethod.POST)
    public ResponseBodyDto toPayed(@RequestBody Map<String, Long> requestData) {
        try {
            if (requestData.get("orderId") == null) throw new Exception("订单ID不能为空");
            orderService.toPayed(requestData.get("orderId"));
        } catch (EntityNotFoundException entityNotFoundException) {
            return new ResponseBodyDto(500, "订单不存在");
        } catch (Exception exception) {
            return new ResponseBodyDto(500, exception.getMessage());
        }

        return new ResponseBodyDto(200, "支付成功");
    }

    @RequestMapping(value = "/cancel", method = RequestMethod.POST)
    public ResponseBodyDto cancel(@RequestBody Map<String, Long> requestData) {
        String resultMsg = null;
        try {
            if (requestData.get("orderId") == null) throw new Exception("订单ID不能为空");
            resultMsg = orderService.cancel(requestData.get("orderId"));
        } catch (EntityNotFoundException entityNotFoundException) {
            return new ResponseBodyDto(500, "订单不存在");
        } catch (Exception exception) {
            return new ResponseBodyDto(500, exception.getMessage());
        }

        return new ResponseBodyDto(200, resultMsg);
    }

    @RequestMapping(value = "/toCancelled", method = RequestMethod.POST)
    public ResponseBodyDto toCancelled(@RequestBody @NotNull @NotEmpty Map<String, List<Long>> requestData) {
        try {
            if (requestData.get("orderIds").isEmpty()) throw new Exception("订单ID不能为空");
            orderService.toCancelled(requestData.get("orderIds"));
        } catch (EntityNotFoundException entityNotFoundException) {
            return new ResponseBodyDto(500, "订单不存在");
        } catch (Exception exception) {
            return new ResponseBodyDto(500, exception.getMessage());
        }

        return new ResponseBodyDto(200, "通过取消订单成功");
    }

    @RequestMapping(value = "/finish", method = RequestMethod.POST)
    public ResponseBodyDto finish(@RequestBody @NotNull @NotEmpty Map<String, List<Long>> requestData) {
        try {
            if (requestData.get("orderIds").isEmpty()) throw new Exception("订单ID不能为空");
            orderService.finish(requestData.get("orderIds"));
        } catch (Exception exception) {
            return new ResponseBodyDto(500, exception.getMessage());
        }

        return new ResponseBodyDto(200, "所选订单完成");
    }
    @Value("${web.export-path}")
    private String exportPath;

    @Value("${web.excel-path}")
    private String excelPath;

    @RequestMapping(value = "/export", method = RequestMethod.GET)
    public ResponseBodyDto export() {
        String[] titles = {"订单Id", "用户Id", "地址", "创建时间", "支付时间", "订单总价", "订单类型", "订单状态"};
        try {
//            String path = SpringContextUtil.getContext().getResource("classpath:").getURL().getPath();
            DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
            String fileName = dateFormatter.format(new Date()) + ".xlsx";
            File file = new File(Paths.get(".").toAbsolutePath() + exportPath, fileName);
//            File file = new File("jar:"+System.getProperty("user.dir"), fileName);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdir();
            }

            XSSFWorkbook xssfWorkbook = new XSSFWorkbook();
            XSSFSheet xssfSheet = xssfWorkbook.createSheet("订单");

            XSSFRow xssfRow = xssfSheet.createRow(0);
            for (int i = 0; i < titles.length; i++) {
                xssfRow.createCell(i).setCellValue(titles[i]);
            }

            List<OrderDto> orderDtos = orderService.findAll();
            for (int i = 1; i <= orderDtos.size(); i++) {
                XSSFRow row = xssfSheet.createRow(i);
                String address = addressService.findById(orderDtos.get(i - 1).getAddressId()).toString();
                row.createCell(0).setCellValue(orderDtos.get(i - 1).getOrderId());
                row.createCell(1).setCellValue(orderDtos.get(i - 1).getUserId());
                row.createCell(2).setCellValue(address);
                row.createCell(3).setCellValue(dateFormatter.format(new Date(orderDtos.get(i - 1).getCreateTime().getTime())));
                if (orderDtos.get(i - 1).getPurchaseTime() != null)
                    row.createCell(4).setCellValue(dateFormatter.format(new Date(orderDtos.get(i - 1).getPurchaseTime().getTime())));
                else
                    row.createCell(4).setCellValue("");
                row.createCell(5).setCellValue(orderDtos.get(i - 1).getTotalPrice().toString());
                row.createCell(6).setCellValue(orderDtos.get(i - 1).getStatus().toString());
            }

            FileOutputStream fileOutputStream = new FileOutputStream(file);
            xssfWorkbook.write(fileOutputStream);

            Map<String, String> data = new HashMap<>();
            data.put("url", excelPath + fileName);
            
            return new ResponseBodyDto(200, "导出成功", data);
        } catch (Exception exception) {
            return new ResponseBodyDto(500, exception.getMessage());
//            return ResponseEntity.badRequest().contentType(MediaType.APPLICATION_JSON).body((new Gson()).toJson(new ResponseBodyDto(500, exception.getMessage())));
        }
    }
}
